<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>echarts 折线图 + 柱状图（包含负数，dataZoom 作用于两个 x 轴）</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"></script>
</head>

<body>
    <div id="chart" style="width: 1200px; height: 600px;"></div>

    <script type="text/javascript">

        var chart = echarts.init(document.getElementById('chart'));

        const fakeData = [
            {
                "chartList": [
                    {
                        "indexFactor": "F_NMYCR",
                        "indexFactorName": "环比变化：右",
                        "lineType": 5,
                        "indexUnit": null,
                        "dataList": [
                            -0.200000000000003,
                            -1.3,
                            -1.8,
                            0.899999999999999,
                            -1.5,
                            0.299999999999997,
                            -0.399999999999999,
                            -1,
                            -0.400000000000006,
                            0,
                            -0.699999999999996,
                            0,
                            0.399999999999999,
                            -7.2,
                            -3.5,
                            -2,
                            0,
                            -1.4,
                            1.09999999999999,
                            -0.5,
                            1,
                            -0.199999999999996
                        ],
                        "ydirection": 1
                    },
                    {
                        "indexFactor": "F_PMINM1",
                        "indexFactorName": "2024-11",
                        "lineType": 0,
                        "indexUnit": null,
                        "dataList": [
                            50,
                            45.9,
                            48.2,
                            57,
                            49.1,
                            48.8,
                            45.4,
                            42.7,
                            45.3,
                            51.2,
                            49.7,
                            43.5,
                            55.6,
                            48,
                            48.6,
                            40.7,
                            50.1,
                            46.4,
                            57.3,
                            49.3,
                            48.8,
                            46.2
                        ],
                        "ydirection": 0
                    },
                    {
                        "indexFactor": "F_NMBL",
                        "indexFactorName": "荣枯线",
                        "lineType": 1,
                        "indexUnit": null,
                        "dataList": [
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50,
                            50
                        ],
                        "ydirection": 0
                    }
                ],
                "xvalueList": [
                    { "xvalueGroup": "非制造业", "xvalue": "商务活动" },
                    { "xvalueGroup": "非制造业", "xvalue": "新订单" },
                    { "xvalueGroup": "非制造业", "xvalue": "新出口订单" },
                    { "xvalueGroup": "非制造业", "xvalue": "业务活动预期" },
                    { "xvalueGroup": "非制造业", "xvalue": "投入品价格" },
                    { "xvalueGroup": "非制造业", "xvalue": "销售价格" },
                    { "xvalueGroup": "非制造业", "xvalue": "从业人员" },
                    { "xvalueGroup": "非制造业", "xvalue": "在手订单" },
                    { "xvalueGroup": "非制造业", "xvalue": "存货" },
                    { "xvalueGroup": "非制造业", "xvalue": "供应商配送时间" },
                    { "xvalueGroup": "建筑业", "xvalue": "建筑业" },
                    { "xvalueGroup": "建筑业", "xvalue": "新订单" },
                    { "xvalueGroup": "建筑业", "xvalue": "业务活动预期" },
                    { "xvalueGroup": "建筑业", "xvalue": "投入品价格" },
                    { "xvalueGroup": "建筑业", "xvalue": "销售价格" },
                    { "xvalueGroup": "建筑业", "xvalue": "从业人员" },
                    { "xvalueGroup": "服务业", "xvalue": "服务业" },
                    { "xvalueGroup": "服务业", "xvalue": "新订单" },
                    { "xvalueGroup": "服务业", "xvalue": "业务活动预期" },
                    { "xvalueGroup": "服务业", "xvalue": "投入品价格" },
                    { "xvalueGroup": "服务业", "xvalue": "销售价格" },
                    { "xvalueGroup": "服务业", "xvalue": "从业人员" }
                ]
            }
        ];

        
        function formatterData (data) {
            const obj = {}

            obj.xvalueGroup = data[0].xvalueList.map(v => v.xvalueGroup);
            obj.xAxisData = data[0].xvalueList.map(v => v.xvalue);
            // 生成groupSeparates
            obj.groupSeparates = obj.xvalueGroup.map((v, i, arr) => {
                 if (i === 0) return true;
                 if (v == arr[i-1]) {
                    return false;
                 } else {
                    return true;
                 }
            });
            // 反过来将第一个 obj.xvalueGroup 中多余的重复分组重置为空字符串
            obj.xvalueGroup = obj.xvalueGroup.map((v, i) => {
                if (obj.groupSeparates[i]) return v;
                return  ""
            });
            return obj
        }
        const partData = formatterData(fakeData);
        console.log('结构化数据', partData);

        // 指定图表的配置项和数据
        var option = {
            title: {
                text: '折线图 + 柱状图（包含负数，dataZoom 作用于两个 x 轴）'
            },
            grid: { bottom: 120 },

            xAxis: [
                {
                    position: "bottom",
                    data: partData.xAxisData,
                    axisTick: {
                        length: 10 // 刻度线的长度
                    },
                    offset: 14,
                    axisLabel: {
                        interval: 0,
                        formatter: function (value) {
                            return value.split("").join("\n");
                        }
                    }
                },
                {
                    position: "bottom",
                    data: partData.xvalueGroup,
                    axisTick: {
                        length: 80,
                        inside: false,
                        interval: function(index, value) {
                            return partData.groupSeparates[index]; // 根据标识分组的刻度线
                        }
                    },
                    axisLabel: {
                        interval:2,
                        formatter: function(value, index) {
                            return `{label|${value}}`; // 使用rich样式
                        },
                        rich: {
                            label: {
                                align: 'center',  // 水平居中
                                verticalAlign: 'middle', // 垂直居中
                                padding: [0, 50] // 适当的间距
                            }
                        }
                    }
                }
            ],
            yAxis: {
                type: 'value', // 设置为数值轴
            },
            series: [
                {
                    name: '柱状图',
                    type: 'bar', // 柱状图
                    data: fakeData[0].chartList[0].dataList,                   
                },
                {
                    name: '折线图',
                    type: 'line', // 折线图
                    data: fakeData[0].chartList[1].dataList,
                    
                }
            ],
            dataZoom: [
                {
                    type: 'slider',
                    xAxisIndex: [0, 1], // 指定作用于第一个和第二个 x 轴
                    start: 0, // 初始显示数据的起始百分比
                    end: 100, // 初始显示数据的结束百分比
                }
            ]
        };

        // 绘制图表
        chart.setOption(option);

    </script>

</body>
</html>
